package com.baidu.jiuhao.es.service;


import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baidu.jiuhao.es.authconf.JiuhaoConfig;
import com.baidu.jiuhao.es.req.DocSearchRequest;
import com.baidu.jiuhao.es.util.BceV1Signer;
import com.baidu.jiuhao.es.util.EsUtils;
import com.baidubce.auth.SignOptions;
import com.baidubce.http.HttpMethodName;
import com.baidubce.internal.InternalRequest;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class SearchDocService {


    private final JiuhaoConfig jiuhaoConfig;

    private final BceCredentialsService bceCredentialsService;


    /**
     * doc / video / web /  检索
     *
     * @param request
     * @return
     */


    public JSONObject searchDocs(DocSearchRequest request) {
        // 参数校验
        if (request.getAgentId() == null || request.getAgentId().isEmpty()) {
            throw new IllegalArgumentException("agent_id参数不能为空");
        }

        // 检查索引是否存在
        /*  EsUtils.checkIndicesExist(client, arrayIndex);*/

        // 创建搜索请求
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());

        // 创建搜索源构建器
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 构建基础查询
        BoolQueryBuilder boolQuery = this.buildBaseQuery(request);
        sourceBuilder.query(boolQuery);

        // 动态计算聚合size，确保覆盖当前页的文档
        int aggregationSize = Math.max(request.getPageNum() * request.getPageSize(), 100);

        // 配置聚合
        sourceBuilder.aggregation(AggregationBuilders.terms("docs_by_document_id")
                .field("document_id")
                .size(aggregationSize)
                .subAggregation(AggregationBuilders.topHits("top_docs")
                        .size(1)
                        .sort(SortBuilders.scoreSort().order(SortOrder.DESC))
                        .fetchSource(null, new String[]{"vector"}) // 排除vector字段
                )
        );

        // 仅获取聚合结果
        sourceBuilder.size(0);
        searchRequest.source(sourceBuilder);
        // 打印生成的DSL
        log.info("生成的DSL: ");
        EsUtils.printPrettyDSL(sourceBuilder.toString());
        log.info("分页参数: pageNum={}, pageSize={}", request.getPageNum(), request.getPageSize());


        InternalRequest internalRequest = new InternalRequest(HttpMethodName.POST, URI.create(jiuhaoConfig.getUrl()));
        //internalRequest.setHeaders(ImmutableMap.of("Host", "dev.bcetest.baidu.com:8091"));

        SignOptions signOptions = new SignOptions();
        signOptions.setHeadersToSign(Sets.newHashSet("host"));

        new BceV1Signer().sign(internalRequest, bceCredentialsService,signOptions);
        Map<String, String> headers = internalRequest.getHeaders();
        String authorization = MapUtil.getStr(headers, "Authorization");
        log.info("Authorization: {}", authorization);

        JSONObject jsonObject = this.sendHttp(sourceBuilder.toString(), request.getAgentId(), authorization);
        return jsonObject;
        /*try {
            // 执行搜索请求
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

            // 存储文档结果
            List<Map<String, Object>> documents = new ArrayList<>();
            // 获取聚合结果
            Aggregations aggregations = searchResponse.getAggregations();
            if (aggregations == null) {
                log.warn("聚合结果为空，可能无匹配数据或配置错误");
                return new DocSearchResponse(0L, new ArrayList<>());
            }
            Terms terms = aggregations.get("docs_by_document_id");

            long total = 0;
            int startIndex = (request.getPageNum() - 1) * request.getPageSize();
            int endIndex = startIndex + request.getPageSize();

            if (terms != null) {
                // 计算总文档数（所有分组的doc_count之和）
                total = terms.getBuckets().stream()
                        .mapToLong(Terms.Bucket::getDocCount)
                        .sum();

                List<Terms.Bucket> buckets = (List<Terms.Bucket>) terms.getBuckets();
                log.info("聚合结果: 总分组数={}, 当前页文档数={}", buckets.size(), endIndex - startIndex);

                // 遍历聚合桶并应用分页
                for (int i = 0; i < buckets.size() && i < endIndex; i++) {
                    if (i >= startIndex) {
                        Terms.Bucket bucket = buckets.get(i);
                        // 获取TopHits聚合结果
                        TopHits topHits = bucket.getAggregations().get("top_docs");
                        SearchHit[] hits = topHits.getHits().getHits();

                        if (hits.length > 0) {
                            // 存储文档信息
                            Map<String, Object> doc = new HashMap<>();
                            doc.put("document_id", bucket.getKeyAsString());
                            doc.put("doc_count", bucket.getDocCount());
                            doc.put("score", hits[0].getScore());
                            doc.put("source", hits[0].getSourceAsMap());
                            documents.add(doc);
                        }
                    }
                }
            }

            // 返回搜索结果（修正后的total和分页文档）
            return new DocSearchResponse(total, documents);
        } catch (IOException e) {
            // 抛出运行时异常
            throw new RuntimeException("Error while searching documents", e);
        }*/
    }

    private BoolQueryBuilder buildBaseQuery(DocSearchRequest request) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        // 收集所有 agent_id 值（包括原始 agentId 和 publicAgentId）
        List<String> agentIds = new ArrayList<>();

        // 添加原始 agent_id（必填）
        if (request.getAgentId() != null && !request.getAgentId().isEmpty()) {
            agentIds.add(request.getAgentId());
        }

        // 添加 publicAgentId（可选）
        agentIds.add(jiuhaoConfig.getPublicAgentId());


        // 创建 terms 查询：agent_id IN [value1, value2]
        boolQuery.filter(QueryBuilders.termsQuery("agent_id", agentIds));

        // 添加 dir_id（可选）
        if (request.getDirId() != null && !request.getDirId().isEmpty()) {
            boolQuery.filter(QueryBuilders.termQuery("dir_id", request.getDirId()));
        }

        // 添加 version（可选）
        if (request.getVersion() != null && !request.getVersion().isEmpty()) {
            boolQuery.filter(QueryBuilders.termQuery("version", request.getVersion()));
        }

        // 添加 label（可选）
        if (request.getLabels() != null && !request.getLabels().isEmpty()) {
            boolQuery.filter(QueryBuilders.termsQuery("label", request.getLabels()));
        }

        // 添加 available（可选）
        if (request.getAvailable() != null) {
            boolQuery.filter(QueryBuilders.termQuery("available", request.getAvailable()));
        }

        // 添加全文检索（生成相关度分数）
        if (request.getKeyword() != null && !request.getKeyword().isEmpty()) {
            MatchPhraseQueryBuilder phraseQuery = QueryBuilders.matchPhraseQuery("sentence_content", request.getKeyword());
            phraseQuery.slop(1); // 设置允许的最大间隔
            boolQuery.must(phraseQuery);
        }

        return boolQuery;
    }

    public JSONObject sendHttp(String dsl, String agentId, String authorization) {
        OkHttpClient client = new OkHttpClient();
        Map<Object, Object> map = MapUtil.builder()
                .put("agentId", agentId)
                .put("publicAgentId", jiuhaoConfig.getPublicAgentId())
                .put("env", jiuhaoConfig.getEnv())
                .put("datasetId", jiuhaoConfig.getDatasetId())
                .put("dsl", dsl)
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, JSONUtil.toJsonStr(map));
        Request request = new Request.Builder()
                .url(jiuhaoConfig.getUrl())
                .post(body)

                .addHeader("accept", "application/json")
                .addHeader("content-type", "application/json")
                //.addHeader("sec-ch-ua", "Google Chrome;v="135", "Not-A.Brand";v="8", "Chromium";v="135)
                .addHeader("authorization", authorization)
                .addHeader("Host", "ky-rd.cloud.baidu.com")
                .build();

        try {
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                JSONObject responseJson = new JSONObject(response.body());
                log.info("http请求结果:{}", responseJson);
                return responseJson;
            } else {
                log.warn("返回码：{}", response.code());
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return JSONUtil.parseObj("{}");
    }


}
